<?php
/**********************
**hardware_intellistrip_server.inc
**Date Created: 4/13/2009
**Copyright 2009 Tomorrow Tech Industries
**Contact: RPITomorrowTech@gmail.com
**********************/

/**********************
This uses a special hardware device attached to a serial port to actually control things
./intellistrip <serial device> 

**********************/

require_once('shared/errors.inc');
require_once('shared/intellistrip.inc');
require_once('db_access.inc');
require_once('intellistrip_server.inc');
require_once('software_intellistrip_db.inc');

//Default location for the executable
define('INTELLISTRIP_EXE', '/opt/intellimation/intellistrip');

/***************************************************************
Example function calls:
	-p portnumber
	-s setportpower
		-l level
	-g getIntellistrip info
	-q portpower

	intellistrip -p 1 -q  //Get port power for port 1
	intellistrip -g  //Get intellistrip info
	intellistrip -s -p 3 -l 100   //Set port 3 power to 100
*****************************************************************/

define('PORT_NUMBER', '-p');
define('SET_PORT_POWER', '-s');
define('POWER_LEVEL', '-l');
define('GET_INTELLISTRIP_INFO', '-g');
define('GET_PORT_POWER', '-q');

class HardwareIntellistripServer extends IntellistripServer
{
	//Location of the executable
	private $exeLocation = INTELLISTRIP_EXE;

	/*********
	Initialization
	********/

	public function SoftwareIntellistripServer()
	{
	}
	

	/*********
	Accessor/mutator
	********/

	/*********
	XML-RPC called functions
	*********/
		
	public function setPortPower($portID, $powerLevel)
	{
		//All numbers in base 10 unless otherwise specified
		//Set power level for port 1, set level to 100	
		//First line of output: return code number as an ASCII string
		//Second line will be an error message
		//Command itself should return 0 on success		
		$output = array();
		$result = 0;
		
		$cmd = INTELLISTRIP_EXE . " " . PORT_NUMBER . " " . $portID . " " . POWER_LEVEL . " " . $powerLevel . " " . SET_PORT_POWER;
		exec($cmd, $output, $result);
		
		if( $result != 0 )
		{
			//This means there was an error, and we are aborting the function.
			$this->setLastError("bad rc, command: " . $cmd . ', output: ' . $output);
			return TT_GENERAL;
		}
		if(count($output) < 2)
		{
			//Function did not return the correct amount of lines.
			$this->setLastError("not enough lines");
			return TT_GENERAL;
		}
		
		$rc = $output[0];
		$error = $output[1];
		
		if(TT_FAILED($rc))
		{
			$this->setLastError("exe failed: " . $error);
			return $rc;
		}
		
		return TT_OK;
	}

	//Get device power
	//
	public function getPortPower($portID, &$powerLevel)
	{
		$output = array();
		$result = 0;
				
		$cmd = INTELLISTRIP_EXE . " " . PORT_NUMBER . " " . $portID . " " . GET_PORT_POWER;		
		exec($cmd, $output, $result);

		if($result != 0)
		{
			//This means there was an error, and we are aborting the function.
			$this->setLastError("bad rc, command: " . $cmd . ', output: ' . $output);
			return TT_GENERAL;
		}
		if(count($output) < 3)
		{
			//Function did not return the correct amount of lines.
			$this->setLastError("not enough lines");
			return TT_GENERAL;
		}
		
		$rc = $output[0];
		$error = $output[1];
		$powerLevel = $output[2];	
		
		if(TT_FAILED($rc))
		{
			$this->setLastError("exe failed: " . $error);
			return $rc;
		}
		return TT_OK;
	}

	/********************
	Misc
	********************/
	/*******************
	Query device information
	Note this is NOT password protected
	This function is intended for rare queries to get full device status
	
	vendorName: vendor supplied name.
		modelNumber: a number unique with respect to a vendor name to identify 
			different products 
		serialNumber: a number unique to an individual device when combined
			with the vendor name and model number
		numberPorts: the number of ports availible on the device
		state: is the power strip on and availible?
	*******************/
	public function getIntellistripInformation(&$vendorName, &$modelNumber, 
									&$modelVersion, &$serialNumber,
									&$numberPorts, &$state)
	{
		$output = array();
		$result = 0;
		
		$cmd = INTELLISTRIP_EXE . " " . GET_INTELLISTRIP_INFO;
		exec($cmd, $output, $result);
		
		if( $result != 0 )
		{
			$this->setLastError("bad rc, command: " . $cmd . ', output: ' . $output);
			return TT_GENERAL;
		}
		if(!count($output) >= 8)
		{
			//Function did not return the correct amount of lines.
			return TT_GENERAL;
		}
		
		$rc = $output[0];
		$error = $output[1];
		$vendorName = $output[2];
		$modelNumber = $output[3];
		$modelVersion = $output[4];
		$serialNumber = $output[5];
		$numberPorts = $output[6];
		$state = $output[7];
		
		
		
		
		if(TT_FAILED($rc))
		{
			$this->setLastError("Intellistrip_exe Failed");
			return $error;
		}
		
		//Each parameter as listed will be returned in order, each on its own line
		//
		/*  Database stuff. ....I think.  To be removed************
		//echo "Entery, portID: " . $portID . "<BR>";
		$rc = DBConnection::getReadConnection($connection);
		if( TT_FAILED($rc) )
		{
			$this->setLastError("Connect failed");
			return $rc;
		}

		//No matter how the main data structure changes, this shoudld take care of anything
		$query="SELECT * FROM " . SW_INTELLISTRIP__DB__INTELLISTRIP . " LIMIT 1";
		$result=mysql_query($query)
			or $rc = TT_GENERAL;
		if( TT_FAILED($rc) )
		{
			mysql_close($connection);
			$this->setLastError("Query failed: " . $query);
			return $rc;
		}
		$row = mysql_fetch_array($result);
		mysql_close($connection);

		$vendorName = $row[SW_INTELLISTRIP__DB__INTELLISTRIP__VENDOR_NAME];
		$modelNumber = $row[SW_INTELLISTRIP__DB__INTELLISTRIP__MODEL_NUMBER];
		$modelVersion = $row[SW_INTELLISTRIP__DB__INTELLISTRIP__MODEL_VERSION];
		$serialNumber = $row[SW_INTELLISTRIP__DB__INTELLISTRIP__SERIAL_NUMBER];
		$state = $row[SW_INTELLISTRIP__DB__INTELLISTRIP__STATE];
		
		//Number ports must be counted
		$rc = $this->getNumberPorts($numberPorts);
		if( TT_FAILED($rc) )
		{
			return $rc;
		}
		******************End Database stuff***/
		return TT_OK;
	}
	
	/****** What is this doing here? Not using data base, so this can be deleted ********
	public function getNumberPorts(&$numberPorts)
	{
		//Extra line is the number of ports
		$result = system(INTELLISTRIP_EXE . " -p 1 -l 100");			
		$lines = split("\n", $result);
		$rc = $lines[0];
		$error = $lines[1];
		$portID = $lines[2];
		$powerLevel = $lines[3];
		
		if(TT_FAILED($rc))
		{
			$this->setLastError("Intellistrip_exe Failed");
			return $error;
		}
		
	
		//echo "Entery, portID: " . $portID . "<BR>";
		$rc = DBConnection::getReadConnection($connection);
		if( TT_FAILED($rc) )
		{
			$this->setLastError("Connect failed");
			return $rc;
		}

		//No matter how the main data structure changes, this shoudld take care of anything
		$query="SELECT COUNT(*) FROM " . SW_INTELLISTRIP__DB__INTELLISTRIP_PORT;
		$result=mysql_query($query)
			or $rc = TT_GENERAL;
		if( TT_FAILED($rc) )
		{
			mysql_close($connection);
			$this->setLastError("Query failed: " . $query);
			return $rc;
		}
		$row = mysql_fetch_array($result);
		mysql_close($connection);

		//I seem to recall sometimes nothing is returned for empty table
		$numberPorts = $row[0];
		return TT_OK;
	}
	
	*************************************************/
	
	//changePassword
	//newPassword: what Intellistrip's authentication password will be set to if succeeded
	public function changePassword($newPassword)
	{
		return TT_UNSUPPORTED;
	}
	
	/*********
	Utility functions
	*********/
}
?>
